package io.esirong.widget.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * 轮进度条动画
 * 思路：执行外郭动画。默认情况是矩形，你需要指定半径来获得圆解效果
 */

public class CircleProgressBar extends View {

    private final String TAG = CircleProgressBar.class.getSimpleName();
    /**
     * 圆周的角度
     */
    private static final Float CIRCULAR = 360f;

    /**
     * 画笔
     */
    private Paint mPaint = new Paint();

    /**
     * 进度
     */
    private float mProgress = 50;

    /**
     * 最大进度
     */
    private int mMaxProgress = 100;

    /**
     * 圆心颜色
     */
    private int mBackgroundColor = Color.parseColor("#00000000");

    /**
     * 边框颜色，也就是进度的颜色
     */
    private int mProgressBorderColor = Color.parseColor("#358BFF");

    /**
     * 边框颜色，也就是进度条补全的颜色
     */
    private int mBorderColor = Color.parseColor("#40E1E1E1");

    /**
     * 边框的宽度，也就是进度条的宽度
     */
    private int mBorderWidth = 20;

    /**
     * 自身的宽高
     */
    private int mWidth, mHeight;

    /**
     * 半径
     */
    private int mRadius;

    /**
     * 矩形区域
     */
    private RectF mContentRectF = new RectF();

    /**
     * 是否打开过度模式，也就是我们平时看到的类似追赶的效果
     */
    private boolean mIsIntermediateMode;
    /**
     * 旋转当前
     */
    private boolean mIsIntermediateMode2 = false;

    /**
     * 最小弧度，进度条过度模式最小的弧度
     */
    private int mMinProgress = 5;

    /**
     * 过度动画的时间
     */
    private static final int DURATION_DEF = 5000;
    /**
     * 过度动画的时间
     */
    private int duration = DURATION_DEF;
    /**
     * 过度动画
     */
    private ValueAnimator valueAnimator;

    /**
     * 开始角度，在过度动画中使用
     */
    private float mStartAngle = -90f;
    /**
     * 开始角度，在过度动画中使用
     */
    private float mStartAngleOStop = -90f;
    /**
     * 开始角度，在过度动画中使用
     */
    private float mSweepAngle = 90f;

    private int status = 1;
    private final int status_HARD = 1;
    private final int status_HARD2 = 2;

    /**
     * 停止并显示最终态
     */
    public boolean stopToEnd = false;
    /**
     * 停止并显示最初态
     */
    public boolean stopToStart = false;

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        // 去除锯齿
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);

    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        start1();
        start();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

    }

    public void start(int status) {
        this.mMinProgress = 0;
        this.status = status;
    }

    public void start1() {
        start(status_HARD);
    }

    public void start2() {
        start(status_HARD2);
    }

    public void stop() {
        stopToStart();
    }

    public void stopToEnd() {
        stopToEnd = true;
    }

    public void stopToStart() {
        stopToStart = true;
    }

    public void setBorderWidth(int size) {
        mBorderWidth = size;
    }

    /**
     * 设置进度
     */
    public void setProgress(float progress) {
        this.mProgress = progress;
        invalidate();
    }

    /**
     * 设置背景颜色
     */
    public void setBackColor(int backgroundColor) {
        this.mBackgroundColor = backgroundColor;
    }

    /**
     * 获取背景颜色
     */
    public int getBackColor() {
        return this.mBackgroundColor;
    }

    /**
     * 设置进度条的背景颜色
     */
    public void setProgressBackgroundColor(int color) {
        this.mBorderColor = color;
    }

    /**
     * 获取进度条背景颜色
     */
    public int getProgressBackgroundColor() {
        return this.mBorderColor;
    }

    /**
     * 获取进度条的颜色
     */
    public int getProgressColor() {
        return this.mProgressBorderColor;
    }

    /**
     * 设置进度条的颜色
     */
    public void setProgressColor(int color) {
        this.mProgressBorderColor = color;
    }

    public void setDuration(int duration) {
        this.duration = duration;
    }

    public void start() {
        startIntermediateAnim();
    }

    /**
     * 是否是过度模式
     */
    public boolean isIntermediateMode() {
        return mIsIntermediateMode;
    }

    /**
     * 设置过度模式
     */
    public void setIntermediateMode(boolean intermediateMode) {
        if (mIsIntermediateMode != intermediateMode) {
            this.mIsIntermediateMode = intermediateMode;
            // 取消动画
            if (!mIsIntermediateMode) {
                valueAnimator.cancel();
            } else {
                //这里要开启动画
                startIntermediateAnim();
            }
            invalidate();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        mRadius = mWidth > mHeight ? mHeight / 2 : mWidth / 2;
        // 计算要绘制的区域
        mContentRectF.set(mWidth / 2 - mRadius + mBorderWidth / 2, mHeight / 2 - mRadius + mBorderWidth / 2,
                mWidth / 2 + mRadius - mBorderWidth / 2, mHeight / 2 + mRadius - mBorderWidth / 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawIntermediateProgress(canvas);

    }

    /**
     * 绘制过度进度条
     */
    private void drawIntermediateProgress(Canvas canvas) {
        // 首先画出背景圆
        mPaint.setColor(mBackgroundColor);
        mPaint.setStyle(Paint.Style.FILL);
        // 这里减去了边框的宽度
        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius - mBorderWidth, mPaint);
        // 绘制当前的进度

        // 画出进度条
        mPaint.setColor(mProgressBorderColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mBorderWidth);
        // 计算圆弧划过的角度
        float angle = (CIRCULAR / mMaxProgress) * mProgress;

        float startAngle = mStartAngle;
        //
        if (0 == status) {
            startAngle = -90F;
            if (stopToEnd || stopToStart) {
                startAngle = 0;
                angle = 0;
            }
        }

        if (status_HARD == status) {
            startAngle = (CIRCULAR / mMaxProgress * mProgress) + (-90F);
            angle = mSweepAngle;
            if (stopToEnd || stopToStart) {
                startAngle = 0;
                angle = 0;
            }
        }
        if (2 == status) {
            startAngle = mStartAngle;
            angle = CIRCULAR / mMaxProgress * mProgress;
            if (stopToEnd || stopToStart) {
                startAngle = 0;
                angle = 0;
            }
        }
        Log.e(TAG, "angle=" + angle);
        // 这里要画圆弧
        canvas.drawArc(mContentRectF, startAngle, angle, false, mPaint);

        // 画出另一部分的进度条
        mPaint.setColor(mBorderColor);
        mPaint.setStrokeWidth(mBorderWidth);
        // 这里要画圆弧(底）
        canvas.drawArc(mContentRectF, -90F, 360F, false, mPaint);

        if (stopToEnd) {
            mPaint.setColor(mProgressBorderColor);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBorderWidth);
            canvas.drawArc(mContentRectF, -90F, 360F, false, mPaint);
        }
        if (stopToStart) {
            // 画出另一部分的进度条
            mPaint.setColor(mBorderColor);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBorderWidth);
            // 这里要画圆弧(底）
            canvas.drawArc(mContentRectF, -90F, 360F, false, mPaint);
        }
    }

    public void drawOnStop() {

    }

    public void setNormal(boolean ismIsIntermediateMode2) {
        this.mIsIntermediateMode2 = ismIsIntermediateMode2;
    }

    /**
     * 开始过度动画
     */
    private void startIntermediateAnim() {
        if (valueAnimator == null) {
            valueAnimator = ValueAnimator.ofFloat(mMinProgress, mMaxProgress - mMinProgress);
            valueAnimator.setDuration(duration);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float value = (float) valueAnimator.getAnimatedValue();
                    setProgress(value);
                    mStartAngle += 2;
                }

            });
            valueAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {

                }

                @Override
                public void onAnimationEnd(Animator animator) {

                }

                @Override
                public void onAnimationCancel(Animator animator) {

                }

                @Override
                public void onAnimationRepeat(Animator animator) {

                    if (stopToEnd || stopToStart) {
                        setProgress(0);
                        valueAnimator.end();
                        return;
                    }
                    mStartAngle = mStartAngle - CIRCULAR / mMaxProgress * mMinProgress;
                }
            });
        }
        valueAnimator.setRepeatCount(-1);
        valueAnimator.start();
    }

    /**
     * 绘制进度条
     */
    private void drawProgress(Canvas canvas) {
        // 开始画进度条
        // 首先画出背景圆
        mPaint.setColor(mBackgroundColor);
        mPaint.setStyle(Paint.Style.FILL);
        // 这里减去了边框的宽度
        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius - mBorderWidth, mPaint);
        // 画出进度条
        mPaint.setColor(mProgressBorderColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mBorderWidth);

        // 计算圆弧划过的角度
        float angle = CIRCULAR / mMaxProgress * mProgress;
        // 这里要画圆弧
        canvas.drawArc(mContentRectF, -90, angle, false, mPaint);
        // 画出另一部分的进度条
        mPaint.setColor(mBorderColor);
        mPaint.setStrokeWidth(mBorderWidth);
        // 这里要画圆弧
        canvas.drawArc(mContentRectF, -90 + angle, CIRCULAR - angle, false, mPaint);
    }
}